package engine;
public class Collision {

	/*
	 * @invariant obj1!=null;
	 * @invariant obj2!=null;
	 * @invariant obj1!=obj2;
	 */
	private /*@ spec_public @*/ PhysicsObject obj1;
	private /*@ spec_public @*/ PhysicsObject obj2;
	private /*@ spec_public @*/ Vertex[] collPts;
	private /*@ spec_public @*/ Vector normal1, normal2;
	private /*@ spec_public @*/ Vector impact;
	/**
	 * Collision Constructor
	 * @param p1 first PhysicsObject in the collision
	 * @param p2 second PhysicsObject in the collision
	 */
	/*
	 * @requires p1!=null;
	 * @requires p2!=null
	 * @ensures impact!=null;
	 */
	public Collision(PhysicsObject p1, PhysicsObject p2)
	{
		if(p1==null){System.out.println("Illegal Input, cannot have Null PhysicsObject");return;}
		if(p2==null){System.out.println("Illegal Input, cannot have Null PhysicsObject");return;}
		if(p2==p1){System.out.println("Illegal Input, cannot have PhysicsObject Colliding with itself");return;}
		obj1 = p1;
		obj2 = p2;
		impact = new Vector((p1.getMass()*p1.getVelocity().getX())+(p2.getMass()*p2.getVelocity().getX()),(p1.getMass()*p1.getVelocity().getY())+(p2.getMass()*p2.getVelocity().getY()));

	}
	/**
	 * getObj2 returns the first PhysicsObject taking part in this collision
	 * @return the first PhysicsObject in this collision
	 */
	/*
	 * @ assignable \nothing;
	 * @ returns obj1;
	 * @ensures \result == obj1;
	 */
	public PhysicsObject getObj1()
	{
		return obj1;
	}
	/**
	 * getObj2 returns the second PhysicsObject taking part in this collision
	 * @return the second PhysicsObject in this collision
	 */
	/*
	 * @ assignable \nothing;
	 * @ returns obj2;
	 * @ensures \result == obj2;
	 */
	public PhysicsObject getObj2() {
		return obj2;
	}	
	/**
	 * setObj2 sets the collision's second object to the passed parameter
	 * @param obj2 object collision's obj2 is to be set to
	 */
	/*
	 * @ assignable obj2;
	 * @requires obj2!=null;
	 * @ensures this.obj2 == obj2;
	 */
	public void setObj2(PhysicsObject obj2) {
		if(obj2==null){System.out.println("Illegal Input, cannot have null PhysicsObject");return;}
		this.obj2 = obj2;
	}
	/**
	 * getCollPts returns the collection of points in collision
	 * @return collPts, set of points in collision
	 */
	/*
	 * @ assignable \nothing;
	 * @ returns collPts;
	 * @ensures \result == collPts;
	 */
	public Vertex[] getCollPts() {
		return collPts;
	}
	/**
	 * setCollPts sets the set of points colliding to the passed array
	 * @param collPts the points of collision collPts is to be set to
	 */
	/*
	 * @ assignable collPts;
	 * @ensures this.collPts == collPts;
	 */
	public void setCollPts(Vertex[] collPts) {
		if(collPts.length!=this.collPts.length)
		{
			this.collPts = new Vertex[collPts.length];
		}
		for(int i = 0;i<collPts.length;i++)
		{
			this.collPts[i] = collPts[i];
		}
	}
	/**
	 * Returns the normal vectors of the collision
	 * @return the normal vectors
	 */
	/*
	 * @ assignable \nothing;
	 * @ensures \result != null;
	 */
	public Vector[] getNormals() {
		Vector[] normals = {normal1, normal2};
		return normals;
	}

	/**
	 * Sets the normal vector of the collision
	 * @param normal1
	 * @param normal2
	 */
	/*
	 * @ assignable normal1;
	 * @requires normal1!=null;
	 * @ assignable normal2;
	 * @requires normal2!=null;
	 * @ensures this.normal1 == normal1;
	 * @ensures this.normal2 == normal2;
	 */
	public void setNormals(Vector normal1, Vector normal2) {
		if(obj1==null){System.out.println("Illegal Input, cannot have null Normal Vector");return;}
		this.normal1 = normal1;
		this.normal2 = normal2;
	}
	/**
	 * Returns the impact of the collision
	 * @return the impact
	 */
	/*
	 * @ assignable \nothing;
	 * @ returns impact;
	 * @ensures \result == impact;
	 */
	public Vector getImpact() {
		return impact;
	}
	/**
	 * setImpact sets the value of the impact of the collision
	 * @param impact value collision's impact will be set to
	 */
	/*
	 * @ assignable impact;
	 * @requires impact!=null;
	 * @ensures this.impact == impact;
	 */
	public void setImpact(Vector impact) {
		if(impact==null){System.out.println("Illegal Input, cannot have null impact");return;}
		this.impact = impact;
	}
	/**
	 * setObj1 sets the collision's first object to the passed parameter
	 * @param obj1 object collision's obj1 is to be set to
	 */
	/*
	 * @ assignable obj1;
	 * @requires obj1!=null;
	 * @ensures this.obj1 == obj1;
	 */
	public void setObj1(PhysicsObject obj1) {
		if(obj1==null){System.out.println("Illegal Input, cannot have null PhysicsObject");return;}
		this.obj1 = obj1;
	}
	/**
	 * toString
	 * Returns a string describing the collision and which objects it involves
	 */
	/*
	 * @ assignable \nothing;
	 * @ returns new String;
	 */
	public String toString()
	{
		return "Collision between\n"+obj1+"\n"+obj2+"\n";
	}

}
